use std::{rc::Rc, cell::RefCell};

use jvm_rust::raw;

use crate::{native, rtda::{Frame, heap::Class, Slot, ExtraType}};

pub fn init() {
    native::register("java/lang/reflect/Array", "newArray", "(Ljava/lang/Class;I)Ljava/lang/Object;", new_array);
}

// private static native Object newArray(Class<?> componentType, int length) throws NegativeArraySizeException;
// (Ljava/lang/Class;I)Ljava/lang/Object;
fn new_array(frame: Rc<RefCell<Frame>>) {
    let vars = frame.borrow().get_local_vars();
    let this = vars.borrow().get_this().unwrap();
    let class_obj = vars.borrow().get_ref(0).unwrap();
    // jclass
    let obj = unsafe { &*class_obj };
    // unconfirmed 231115 应该是用extra获取原class，用原class名称，后续应取消else，
    let class_name = if let Some(ExtraType::Class(class)) = obj.get_extra() {
        class.get_name()
    } else {
        // 这个classname一定是java/lang/Class，应取消这一步。
        // obj.get_class().get_name()
        panic!("需要测试或修改此处。");
    };

    let array_class = obj.get_class().get_class_loader().unwrap().lock().unwrap().load_class("[L".to_string() + &class_name + ";");
    let len = vars.borrow().get_int(1);
    let mut array_class = Class::new_array(array_class, len as usize);
    let stack = frame.borrow().get_operand_stack();
    let mut slot = Slot::default();
    slot.set_ref(Some(raw!(array_class)));
    stack.borrow_mut().push_slot(slot);
}
